package wechat.vo;

import com.alibaba.fastjson.JSON;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import wechat.core.HttpParams;
import wechat.core.HttpTools;

import java.util.Date;

/**
 * Created by CoderJiang@Sina.com on 16-6-28.
 */
public class WeChatAccount {

    final int TOKEN_TIME_OUT = 2 * 3600;

    private String token;

    private Date lastReqAccessToken = null;

    private String appID;

    private String appSecret;

    private static final Logger log = LoggerFactory.getLogger(WeChatAccount.class);

    /**
     * 全局唯一票据
     */
    private String accessToken;

    /**
     * 获取全局唯一票据
     *
     * @return
     */
    public String getUserAccessToken() {
        log.info("getUserAccessToken method");
        if (this.accessToken == null || this.lastReqAccessToken == null || this.isTokenTimeOut()) {
            log.debug("access token timeout, request again");
            this.lastReqAccessToken = new Date();
            HttpParams params = new HttpParams();
            params.addParam("grant_type", "client_credential");
            params.addParam("appid", this.appID);
            params.addParam("secret", this.appSecret);
            String res = HttpTools.get(API.ACCESS_TOKEN + "?" + params.getUrlParam());
            AccessTokenResponse token = JSON.parseObject(res, AccessTokenResponse.class);
            this.accessToken = token.getAccess_token();
            log.debug(token.getAccess_token());
            log.debug(String.valueOf(token.getExpires_in()));
        }
        log.debug("accessToken:" + this.accessToken);
        return this.accessToken;
    }

    /**
     * 检测token是否到期
     *
     * @return
     */
    private boolean isTokenTimeOut() {

        if ((new Date().getTime() - this.lastReqAccessToken.getTime()) / 1000 > this.TOKEN_TIME_OUT) {
            return true;
        }

        return false;
    }

    public String getToken() {
        return token;
    }

    public void setToken(String token) {
        this.token = token;
    }

    public String getAppID() {
        return appID;
    }

    public void setAppID(String appID) {
        this.appID = appID;
    }

    public String getAppSecret() {
        return appSecret;
    }

    public void setAppSecret(String appSecret) {
        this.appSecret = appSecret;
    }

    /**
     * 第三方授权
     */
    public String register(String scope, String callbackURL) {
        String scopeType = "";
        switch (scope) {
            case "snsapi_userinfo":
                scopeType = "snsapi_userinfo";
                break;
            default:
                scopeType = "snsapi_base";
        }
        return API.AUTHORIZE + "?" + "appid=" + this.appID + "&redirect_uri=" + callbackURL + "&response_type=code&scope=" + scopeType + "&state=null#wechat_redirect";
    }

    /**
     * 获取用户的access token
     *
     * @param req
     */
    public UserAccessTokenResponse getUserAccessToken(String code) {
        if (code == null) {
            log.error("获取code失败");
            throw new RuntimeException("获取code失败");
        } else {
            HttpParams params = new HttpParams();
            params.addParam("appid", this.appID);
            params.addParam("secret", this.appSecret);
            params.addParam("code", code);
            params.addParam("grant_type", "authorization_code");
            String res = HttpTools.get(API.USER_ACCESS_TOKEN + "?" + params.getUrlParam());

            UserAccessTokenResponse userToken = JSON.parseObject(res, UserAccessTokenResponse.class);

            return userToken;
        }
    }

    /**
     * 拉取用户信息(需scope为 snsapi_userinfo)
     *
     * @param accessToken
     * @param openId
     * @param lang
     */
    public UserInfo getUserInfo(String accessToken, String openId, String lang) {
        if (accessToken == null || openId == null || lang == null) {
            log.error("参数不能为空");
            throw new RuntimeException("参数不能为空");
        } else {
            HttpParams params = new HttpParams();
            params.addParam("access_token", accessToken);
            params.addParam("openid", openId);
            params.addParam("lang", lang);
            String res = HttpTools.get(API.USERINFO + "?" + params.getUrlParam());

            UserInfo userInfo = JSON.parseObject(res, UserInfo.class);

            return userInfo;
        }
    }

    /**
     * 刷新access_token
     *
     * @param refreshToken
     */
    public UserRefreshTokenResponse refreshToken(String refreshToken) {
        if (refreshToken == null) {
            log.error("refreshToken不能为空");
            throw new RuntimeException("refreshToken不能为空");
        } else {
            HttpParams params = new HttpParams();
            params.addParam("appid", this.appID);
            params.addParam("grant_type", "refresh_token");
            params.addParam("refresh_token", refreshToken);
            String res = HttpTools.get(API.REFRESH_TOKEN + "?" + params.getUrlParam());

            UserRefreshTokenResponse userRefreshToken = JSON.parseObject(res, UserRefreshTokenResponse.class);

            return userRefreshToken;
        }
    }
}
